/*
 * $Id: AbstractOperator.java,v 1.6 2003/05/31 12:07:05 znamenacek Exp $
 *
 * Copyright (c) Tomas Znamenacek
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

package net.sf.vofce.guts;

import java.util.Stack;

/**
 * Implements basic operator code and node management.
 *
 * @author Tomas Znamenacek
 */
public abstract class AbstractOperator implements Operator, Cloneable {

	/**
	 * Operator priority.
	 * The higher number, the higher priority.
	 */
	protected int priority;

	/**
	 * Simple human syntax for the operator.
	 * For example, for the <code>cos(x)</code> function, this
	 * property contains "<code>cos{0}</code>".
	 */
	protected String humanSyntax;

	/**
	 * TeX syntax for the operator.
	 * For example, for the <code>cos(x)</code> function, this
	 * property contains "<code>\\cos{0}</code>".
	 */
	protected String TeXSyntax;

	/**
	 * MathML syntax for the operator.
	 * For example, for the <code>cos(x)</code> function, this
	 * property contains "<code>&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;
	 * &amp;ApplyFunction;&lt;/mo&gt;&lt;mrow&gt;{0}&lt;/mrow&gt;</code>".
	 */
	protected String XMLSyntax;

	public int getPriority() {

		return priority;
	}

	public Operator getFreshInstance() {

		try { return (Operator) clone(); } catch (Exception e) { return null; }
	}
	
	//
	// Node management
	//
	
	/** Left child of this node. */
	protected Operator leftChild = null;

	/** Right child of this node. */
	protected Operator rightChild = null;

	public void setLeftChild(Operator child) {

		leftChild = child;
	}
	
	public void setRightChild(Operator child) {

		rightChild = child;
	}

	public Operator getLeftChild() {

		return leftChild;
	}
	
	public Operator getRightChild() {

		return rightChild;
	}
	
	public boolean isLeaf() {

		return (leftChild == null) && (rightChild == null);
	}

	protected double valueOf(Object arg) {

		return ((Double) arg).doubleValue();
	}
	
	//
	// To be implemented by descendants
	//
	
	public abstract int getArity();
	
	public abstract double evaluateSubTree();

	public abstract String toString(int parentPriority);
	public abstract String toTeX(int parentPriority);
	public abstract String toXML(int parentPriority);
}
